// 基于 SnowLang Project (https://gitee.com/jcnc-org/snow) 的衍生作品
// 原始版权归属: Copyright © 2025 Ke Xu (Luke)
// 本实现版权归属: Copyright © 2025 Sany
// 遵循 Apache License 2.0 授权
package flow

import (
	"errors"
	"fmt"
	"strconv"

	"gitee.com/xntk2381/cc/vm/module"
)

type CallCommand struct{}

func (CallCommand) Execute(parts []string, currentPC int, operandStack *module.OperandStack, localVariableStore *module.LocalVariableStore, callStack *module.CallStack) (int, error) {
	if len(parts) < 3 {
		return 0, errors.New("CALL: need <addr> <nArgs>")
	}

	targetAddr, err := strconv.Atoi(parts[1])
	if err != nil {
		return 0, errors.New("CALL: malformed operands")
	}

	nArgs, err := strconv.Atoi(parts[2])
	if err != nil {
		return 0, errors.New("CALL: malformed operands")
	}

	// build new frame & local table for callee
	calleeLVS := module.NewLocalVariableStore(module.RUN)

	// transfer arguments: operand stack top is last arg
	for slot := nArgs - 1; slot >= 0; slot-- {
		if operandStack.IsEmpty() {
			return 0, errors.New("CALL: operand stack underflow")
		}
		v, err := operandStack.Pop()
		if err != nil {
			return 0, err
		}
		calleeLVS.SetVariable(slot, v)
	}

	newFrame := module.NewStackFrame(currentPC+1, calleeLVS, module.NewMethodContext("subroutine@"+strconv.Itoa(targetAddr), nil))
	callStack.PushFrame(newFrame)

	fmt.Printf("Calling function at address: %d\n", targetAddr)
	return targetAddr, nil
}
